package com.gitee.wsl.scheduler.job.runtime

import com.gitee.wsl.scheduler.job.bean.JobExecutionType
import com.gitee.wsl.ext.map.getOrDefault
import com.gitee.wsl.logger.Logger
import com.gitee.wsl.logger.debug
import com.gitee.wsl.logger.getLogger
import com.gitee.wsl.concurrent.collections.ConcurrentMutableMap


interface JobRegister {
    fun register(runnableJob: RunnableJob)
    fun jobs(executionType: JobExecutionType): Set<String>
    fun get(name: String): RunnableJob

    companion object{
        val Default: JobRegister = create()

        fun create(): JobRegister = DefaultJobRegister()
    }
}



internal class DefaultJobRegister : JobRegister {
    private val logger = Logger.getLogger<DefaultJobRegister>()

    private val jobsMap = ConcurrentMutableMap<String, RunnableJob>()
    private var jobsByExecutionType: Map<JobExecutionType, Set<String>> = emptyMap()

    override fun jobs(executionType: JobExecutionType): Set<String> = jobsByExecutionType.getOrDefault(executionType, emptySet())
    override fun get(name: String): RunnableJob = jobsMap.getValue(name)

    override fun register(runnableJob: RunnableJob): Unit {
        logger.debug("kjob registered a new job named '${runnableJob.job.name}'")
        jobsMap.putIfAbsent(runnableJob.job.name, runnableJob)
        jobsByExecutionType = jobsMap.values.groupBy { it.executionType }.mapValues { it.value.map { it.job.name }.toSet() }
    }
}